const puppeteer = require('puppeteer');
const url = require('url');
const fs = require('fs');

let targetUrl = 'https://sobooks.cc/';

(async function(){
    // 实例化浏览器的配置对象
    let debugOptions = {
        defaultViewport:{
            width:1400,
            height:800
        },
        headless:false,
        slowMo:100
    }
    let options = {headless:true}
    // 实例化浏览器
    const browser = await puppeteer.launch(options);

    try {
        // 获取页面总数
        async function getAllNum() {
            // 打开页面
            const page = await browser.newPage();
            // 截取谷歌请求拦截
            await page.setRequestInterception(true);
            // 监听请求事件，并对请求进行拦截
            page.on('request' , interceptedRequest => {
                // 通过URL模块对请求的地址进行解析
                let urlObj = url.parse(interceptedRequest.url())
                console.log(urlObj);
                if (urlObj.hostname  == 'googleads.g.doubleclick.net') {
                    interceptedRequest.abort();
                } else {
                    interceptedRequest.continue();
                }
            })

            await page.goto(targetUrl);

            // 拿到页面总数所在的元素
            let pageNum = await page.$eval('.pagination ul li:last-child > span' , (eles)=>{
                // 拿到元素里的内容
                let text = eles.innerHTML;
                // 过滤多余的内容和空格
                text = text.substring(1,text.length-2).trim();
                // 把总数返回
                return text
            });

            // 关闭打开的页面,节省性能
            page.close();
            return pageNum
        }

        // 调用总数函数
        // let getPageNum = await getAllNum();
        // console.log(getPageNum);
    } catch (error) {
        console.log(error);
    }

    // 进入到每个列表页面
    async function pageList(num){
        // 列表页的url
        let pageListUrl = 'https://sobooks.cc/page/' + num;

        // 打开列表页
        const page = await browser.newPage();

        // 截取谷歌请求拦截
        await page.setRequestInterception(true);
        // 监听请求事件，并对请求进行拦截
        page.on('request' , interceptedRequest => {
             // 通过URL模块对请求的地址进行解析
            let urlObj = url.parse(interceptedRequest.url())
             // console.log(urlObj);
            if (urlObj.hostname  == 'googleads.g.doubleclick.net') {
                interceptedRequest.abort();
            } else {
                interceptedRequest.continue();
            }
        });

        await page.goto(pageListUrl);

        // 获取到每个页面中所有的书
        let getPageBooks = await page.$$eval('.card .card-item .thumb-img>a' , (elements)=>{
            let arr = [];
            // 循环遍历拿到所有的a
            elements.forEach((item , i)=>{
                // 把需要的属性存进对象
                let objBooks = {
                    // 获取元素的href属性
                    href:item.getAttribute('href'),
                    // 获取元素的title属性
                    title:item.getAttribute('title')
                }
                // 把每个对象存进数组
                arr.push(objBooks);
            })
            // 注意：这个是输出到浏览器中的控制台
            // console.log(arr);
            return arr
        });

        // 关闭页面
        page.close();
        // 通过获取的数组的地址和标题去请求书籍的详情页
        getPageBooks.forEach((item , i)=>{
            getBooksInfo(item);
        });
    }

    // 进入到每个页面中所有书籍的详情页
    async function getBooksInfo(objBooks) {
        // 打开列表页
        const page = await browser.newPage();

        // 截取谷歌请求拦截
        await page.setRequestInterception(true);
        // 监听请求事件，并对请求进行拦截
        page.on('request' , interceptedRequest => {
            // 通过URL模块对请求的地址进行解析
            let urlObj = url.parse(interceptedRequest.url())
            // console.log(urlObj);
            if (urlObj.hostname  == 'googleads.g.doubleclick.net') {
                interceptedRequest.abort();
            } else {
                interceptedRequest.continue();
            }
        })

        // 访问
        await page.goto(objBooks.href);

        try {
            // 等待输入框和按钮出现
            await page.waitForSelector('.e-secret form > .euc-y-i');
            await page.waitForSelector('.e-secret form > .euc-y-s');
    
            // 获取输入框和按钮
            let inputBooks = await page.$('.e-secret form > .euc-y-i');
            let btn = await page.$('.e-secret form > .euc-y-s');
    
            // 聚焦输入框
            await inputBooks.focus();
            // 输入验证码
            let verify = '244152';
            await page.keyboard.type(verify);
            // 点击按钮
            await btn.click();
    
            // 等待下载链接出现,为什么要等呢，因为表单提交之后页面刷新，我们要等到页面加载完成之后再获取元素
            let dowA = await page.waitForSelector('.e-secret b a:nth-child(1)', { timeout: 6000 });

            // 获取下载链接的属性
            let aHref = await dowA.getProperty('href');
            let dowUrlA = await aHref.jsonValue();
            // 截取真正url
            let downloadUrl = dowUrlA.split('?url=')[1];
            console.log('下载链接:', downloadUrl);
            // 创建文件
            let content  = `{"title":"${objBooks.title}" , "href":${objBooks.href}}--- \n`;
            fs.writeFile('book.txt' , content , {flag:'a'} , ()=>{
                console.log('已将书的下载路径写入：' + objBooks.title);
                page.close();
            });
        } catch (error) {
            console.error('获取下载链接时出错:', error);
        } finally {
            // 关闭页面
            await page.close();
        }
    }

    
    pageList(2);

})()


